unit orderin;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  StdCtrls, ExtCtrls, Grids, EditBtn, Spin, Buttons, Menus;

type

  { TOrderInForm }

  TOrderInForm = class(TForm)
    AddItemButton: TButton;
    AddItemEdit: TEdit;
    BitBtn1: TBitBtn;
    CancelButton: TBitBtn;
    DateEdit: TDateEdit;
    GroupBox1: TGroupBox;
    InvoiceTotalEdit: TLabeledEdit;
    ItemLabel: TLabel;
    MenuItem1: TMenuItem;
    PaymentDateEdit: TDateEdit;
    InvoiceEdit: TLabeledEdit;
    OrderDateLabel: TLabel;
    PaymentLabel: TLabel;
    Panel1: TPanel;
    Panel2: TPanel;
    ItemGrid: TStringGrid;
    PopupMenu1: TPopupMenu;
    QuantitySpinEdit: TSpinEdit;
    procedure AddItemButtonClick(Sender: TObject);
    procedure AddItemEditChange(Sender: TObject);
    procedure AddItemEditKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure AddItemEditKeyPress(Sender: TObject; var Key: char);
    procedure BitBtn1Click(Sender: TObject);
    procedure CancelButtonClick(Sender: TObject);
    procedure DateEditAcceptDate(Sender: TObject; var ADate: TDateTime;
      var AcceptDate: Boolean);
    procedure DateEditEditingDone(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure ItemGridGetEditText(Sender: TObject; ACol, ARow: Integer;
      var Value: string);
    procedure ItemGridSelectCell(Sender: TObject; aCol, aRow: Integer;
      var CanSelect: Boolean);
    procedure InvoiceTotalEditExit(Sender: TObject);
    procedure AutoCompleteListBoxClick(Sender: TObject);
    procedure AutoCompleteListMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
    procedure AutoCompleteListBoxKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure MenuItem1Click(Sender: TObject);
  private
    { private declarations }
    AutoCompleteList: TListBox;
    AutoCompleteIndex: TStringList;
  public
    { public declarations }
    SupplierID: string;
    Suppliername: string;
    function GetItem(bc: string):Boolean;
    function ValidateInput: Boolean;
  end;

var
  OrderInForm: TOrderInForm;

implementation

uses main, product, db;

{ TOrderInForm }

procedure TOrderInForm.AddItemButtonClick(Sender: TObject);
var
//  DB: TSQLiteTable;
  r : integer;
  query: String;
  PF: TProductForm;
begin
    if not GetItem(AddItemEdit.Text)
    then
        if MessageDlg('Item not found. Create new product?',
                       mtConfirmation, mbYesNo, 0)=mrYes
        then begin
                     writeln('entering newproduct');
                PF := TProductForm.Create(Self);
                if PF <> nil then
                try
                PF.BarcodeEdit.Text:=AddItemEdit.Text;
                PF.InitCount.Value:=0;
                PF.InitCount.Enabled:=false;
                PF.SupplierBox.ItemIndex:=PF.SupplierBox.Items.IndexOf(Suppliername);
                if PF.ShowNew=mrOK then
                   begin
                     GetItem(AddItemEdit.Text);
                     MainForm.RefreshProductList;
                    MainForm.miApplyUpdates.Enabled := True;
                   end;
                finally
                PF.Free;
                end;
             end;
    AddItemEdit.Text := '';
    QuantitySpinEdit.Value := 0;
    AddItemEdit.SetFocus;
end;

procedure TOrderInForm.AddItemEditChange(Sender: TObject);
var
//  DB: TSQLiteTable;
  r : integer;
  query: String;
begin
  if Length(AddItemEdit.Text) > 4 then
    begin
      //DB := TSQLiteTable.Create(Application);
      AutoCompleteIndex.Clear;
      AutoCompleteList.Clear;
      try
        MainDB.SQL := 'SELECT name, barcode FROM products'
                                 + ' WHERE barcode LIKE "' + AddItemEdit.Text + '%"'
                                 + ' OR name LIKE "%' + AddItemEdit.Text + '%"'
                                 + ' AND suppliercode>-1'    // exclude discounts and departments
                                 + ' ORDER BY name;';
        MainDB.Open;
        if MainDB.State=dsBrowse then
        while not MainDB.EOF do
          begin
    //        test2 :=DB.Fields[0].AsString;
            AutoCompleteList.items.Add( MainDB.Fields[0].AsString );
            AutoCompleteIndex.Add( MainDB.Fields[1].AsString );
            MainDB.Next;
          end;
        AutoCompleteList.Visible := True;
      finally
        MainDB.Close;
      end;
    end;
end;

procedure TOrderInForm.AddItemEditKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key=40
  then if AutoCompleteList.Visible then
       begin
         AutoCompleteList.Tag := 1;   //prevent onClick code from being called
         AutoCompleteList.ItemIndex := 0;
         AutoCompleteList.SetFocus;
         AutoCompleteList.Tag := 0;
         Key := 0;
       end;
end;

procedure TOrderInForm.AddItemEditKeyPress(Sender: TObject; var Key: char);
begin
  if Key = #27 then AutoCompleteList.Visible := false;
end;

procedure TOrderInForm.BitBtn1Click(Sender: TObject);
var
//  DB: TSQLiteTable;
  r: integer;
  i: integer;
  invdate: String;
  paydate: String;
  query: String;
begin
  if ValidateInput then
     begin
       query := '';
       for r := 1 to ItemGrid.RowCount-1 do
           begin
             query := query + 'UPDATE Products SET stocklevel=stocklevel+' + ItemGrid.Cells[5, r]
                      + ', costprice=' + ItemGrid.Cells[3, r]
                      + ', saleprice=' + ItemGrid.Cells[4, r]
                      + ' WHERE barcode="'
                      + ItemGrid.Cells[1,r] + '";';
           end;
       if not MainDB.ExecRemoteSQL(query, true)
                 then ShowMessage( 'Error when updating server');
       MainDB.Close;
       MainForm.miApplyUpdates.Enabled := true;
       { invdate := ToMySQLDate(DateEdit.Text);
       paydate := ToMySQLDate(PaymentDateEdit.Text);
       query := 'INSERT INTO invoices '
                + '(supplier, invoiceref, invoicedate, paymentdue, total, paid) '
                + 'VALUES( ''' + SupplierID
                + ''', ''' + InvoiceEdit.Text
                + ''', ''' + invdate
                + ''', ''' + paydate
                + ''', ' + InvoiceTotalEdit.Text
                + ', 0)';
       if ExecSQL('invoices', query) then
          begin
            i := LastEntryID('invoices');
            if i > -1 then
               for r := 1 to ItemGrid.RowCount-1 do
              begin
                query := 'INSERT INTO goodsreceived '
                      + 'VALUES (' + IntToStr(i)
                      + ', ''' + ItemGrid.Cells[1, r]
                      + ''', ' + ItemGrid.Cells[5, r]
                      + ')';
                if ExecSQL('goodsreceived', query) then
                   begin
                    query := 'UPDATE products '
                          + 'SET cost=' + ItemGrid.Cells[3, r]
                          + ', retail=' + ItemGrid.Cells[4, r]
                          + ', lastcount='
                          + '(SELECT lastcount from products WHERE barcode=' + ItemGrid.Cells[1, r] + ')+' + ItemGrid.Cells[5,r]
                          + ' WHERE barcode=' + ItemGrid.Cells[1, r];
                    if ExecSQL('products', query) then ModalResult := mrOK
                    else ShowMessage('Error updating lastcount of ' + ItemGrid.Cells[2, r]);
                   end
                else ShowMessage('Error adding ' + ItemGrid.Cells[2, r] + 'to goodsreceived');
              end;}
            Close;
          end
       else ShowMessage('Error adding invoice');
end;

procedure TOrderInForm.CancelButtonClick(Sender: TObject);
begin
  if not AutoCompleteList.Visible then ModalResult := mrCancel;
end;

procedure TOrderInForm.DateEditAcceptDate(Sender: TObject;
  var ADate: TDateTime; var AcceptDate: Boolean);
begin
  PaymentDateEdit.Date:=ADate + 30;
end;

procedure TOrderInForm.DateEditEditingDone(Sender: TObject);
begin
  if DateEdit.Date > Now then
     begin
       ShowMessage('Date cannot be in the future');
       DateEdit.SetFocus;
     end;
end;

procedure TOrderInForm.FormCreate(Sender: TObject);
var
  x: Integer;
begin
  ItemGrid.ColWidths[0] := 40;
  DateEdit.Date := Now;
  AutoCompleteIndex := TStringList.Create;
  AutoCompleteList := TListBox.Create(OrderInForm);
  with AutoCompleteList do
       begin
         parent := Self;
         Width := AddItemEdit.Width;
         Height := 280;
         Left := AddItemEdit.Left + AddItemEdit.Parent.Left;
         Top := AddItemEdit.Top + AddItemEdit.Height;
         ClickOnSelChange := false;
         OnClick := @AutoCompleteListBoxClick;
         OnMouseMove := @AutoCompleteListMouseMove;
         OnKeyDown := @AutoCompleteListBoxKeyDown;
         Visible := false;
       end;
end;

procedure TOrderInForm.FormDestroy(Sender: TObject);
begin
  AutoCompleteList.Free;
end;

procedure TOrderInForm.ItemGridGetEditText(Sender: TObject; ACol,
  ARow: Integer; var Value: string);
begin
  if ACol<3 then exit;
  writeln('Get Edit: ',Value);

end;

procedure TOrderInForm.ItemGridSelectCell(Sender: TObject; aCol, aRow: Integer;
  var CanSelect: Boolean);
begin
  TStringGrid(Sender).EditorMode := aCol > 2;
end;

procedure TOrderInForm.InvoiceTotalEditExit(Sender: TObject);
var
  v: double;
begin
  if ActiveControl<> CancelButton then
     begin
       if not TryStrToFloat(TEdit(Sender).Text, v) then
          begin
            ShowMessage('Invalid amount entered');
            TEdit(Sender).SetFocus;
          end;
     end;
end;

procedure TOrderInForm.AutoCompleteListBoxClick(Sender: TObject);
var
  i: LongInt;
begin
  i := AutoCompleteList.ItemIndex;
  writeln(i);
  ItemLabel.Caption := AutoCompleteList.Items[i];
  AddItemEdit.Text := AutoCompleteIndex.Strings[i];

  AutoCompleteList.Visible := false;
  AddItemEdit.SetFocus;
end;

procedure TOrderInForm.AutoCompleteListMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin
  AutoCompleteList.ItemIndex := AutoCompleteList.ItemAtPos(Point(x,y), True);
end;

procedure TOrderInForm.AutoCompleteListBoxKeyDown(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
  if Key=27 then
     begin
       AutoCompleteList.Visible := false;
       AutoCompleteList.Clear;
       AddItemEdit.SetFocus;
     end
  else if Key=13
            //then AutoCompleteListBoxMouseDown(nil, mbLeft, [],0,0);
            then AutoCompleteListBoxClick(Sender);
end;

procedure TOrderInForm.MenuItem1Click(Sender: TObject);
var
  x: Integer;
begin
  If TListBox(Sender).Tag=0 then
  if ItemGrid.Row>0 then
     begin
       for x := ItemGrid.Row to ItemGrid.RowCount-2 do;
           ItemGrid.Rows[x] := ItemGrid.Rows[x+1];
       ItemGrid.RowCount := ItemGrid.RowCount-1;
     end;
end;

function TOrderInForm.GetItem(bc: string): Boolean;
var
  r : integer;
begin
//  DB := TSQLiteTable.Create(nil);
  try
   MainDB.SQL := 'select barcode, name,  costprice, saleprice '
           + 'from Products where barcode="' + bc + '"';
   MainDB.Open;
    if MainDB.RecordCount=1 then
       begin
         r := ItemGrid.RowCount;
         ItemGrid.RowCount := r +1;
         ItemGrid.Cells[0, r] := IntToStr(r);
         ItemGrid.Cells[1, r] := MainDB.FieldByName('barcode').AsString;
         ItemGrid.Cells[2, r] := MainDB.FieldByName('name').AsString;
         ItemGrid.Cells[3, r] := MainDB.FieldByName('costprice').AsString;
         ItemGrid.Cells[4, r] := MainDB.FieldByName('saleprice').AsString;
         ItemGrid.Cells[5, r] := QuantitySpinEdit.Text;
         Result := true;
       end
    else Result := false;
  finally
    MainDB.Close;
  end;
end;

function TOrderInForm.ValidateInput: Boolean;
begin
  result := true;

end;

initialization
  {$I orderin.lrs}

end.

